package com.jetwinner.webfast.module.bigapp.service.impl;

import com.jetwinner.toolbag.ArrayToolkit;
import com.jetwinner.util.EasyStringUtil;
import com.jetwinner.util.FastHashMap;
import com.jetwinner.util.MapUtil;
import com.jetwinner.util.ValueParser;
import com.jetwinner.webfast.image.ImageUtil;
import com.jetwinner.webfast.kernel.AppUser;
import com.jetwinner.webfast.kernel.dao.support.OrderBy;
import com.jetwinner.webfast.kernel.exception.RuntimeGoingException;
import com.jetwinner.webfast.kernel.model.AppPathInfo;
import com.jetwinner.webfast.kernel.service.AppFileService;
import com.jetwinner.webfast.kernel.service.AppUserService;
import com.jetwinner.webfast.module.bigapp.dao.AppGroupDao;
import com.jetwinner.webfast.module.bigapp.dao.AppGroupMemberDao;
import com.jetwinner.webfast.module.bigapp.service.AppGroupService;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author xulixin
 */
@Service
public class AppGroupServiceImpl implements AppGroupService {

    private final AppGroupDao groupDao;
    private final AppGroupMemberDao groupMemberDao;
    private final AppUserService userService;
    private final AppFileService fileService;

    public AppGroupServiceImpl(AppGroupDao groupDao,
                               AppGroupMemberDao groupMemberDao,
                               AppUserService userService,
                               AppFileService fileService) {

        this.groupDao = groupDao;
        this.groupMemberDao = groupMemberDao;
        this.userService = userService;
        this.fileService = fileService;
    }

    @Override
    public int searchGroupsCount(Map<String, Object> conditions) {
        this.prepareGroupConditions(conditions);
        return groupDao.searchGroupsCount(conditions);
    }

    @Override
    public List<Map<String, Object>> searchGroups(Map<String, Object> conditions, OrderBy orderBy,
                                                  Integer start, Integer limit) {

        this.prepareGroupConditions(conditions);
        return groupDao.searchGroups(conditions, orderBy, start, limit);
    }

    private void prepareGroupConditions(Map<String, Object> conditions) {
        if (EasyStringUtil.isNotBlank(conditions.get("ownerName"))) {

            AppUser owner = userService.getUserByUsername(conditions.get("ownerName").toString());

            if (owner != null) {
                conditions.put("ownerId", owner.getId());
            }else{
                conditions.put("ownerId", 0);
            }

        }
        if (conditions.containsKey(("status"))) {
            if (EasyStringUtil.isBlank(conditions.get("status"))) {
                conditions.remove("status");
            }
        }
    }

    @Override
    public int addGroup(AppUser user, Map<String, Object> group) {
        if (EasyStringUtil.isBlank(group.get("title"))) {
            throw new RuntimeGoingException("小组名称不能为空！");
        }

        if (EasyStringUtil.isNotBlank(group.get("about"))) {
            group.put("about", EasyStringUtil.purifyHtml(group.get("about")));
        }
        group.put("ownerId", user.getId());
        group.put("memberNum", 1);
        group.put("createdTime", System.currentTimeMillis());
        int groupId = groupDao.addGroup(group);
        Map<String, Object> member = FastHashMap.build(4)
                .add("groupId", group.get("id"))
                .add("userId", user.getId())
                .add("createdTime", System.currentTimeMillis())
                .add("role", "owner").toMap();
        groupMemberDao.addMember(member);
        return groupId;
    }

    @Override
    public Map<String, Object> getGroup(Integer id) {
        return groupDao.getGroup(id);
    }

    @Override
    public boolean isOwner(Integer groupId, Integer userId) {
        Map<String, Object> group = groupDao.getGroup(groupId);
        return ValueParser.parseInt(group.get("ownerId")) == userId.intValue() ? true : false;
    }

    @Override
    public boolean isAdmin(Integer groupId, Integer userId) {
        Map<String, Object> member = groupMemberDao.getMemberByGroupIdAndUserId(groupId, userId);
        return "admin".equalsIgnoreCase(String.valueOf(member.get("role")));
    }

    @Override
    public boolean isMember(Integer groupId, Integer userId) {
        Map<String, Object> member = groupMemberDao.getMemberByGroupIdAndUserId(groupId, userId);
        return MapUtil.isEmpty(member);
    }

    @Override
    public int searchMembersCount(Map<String, Object> conditions) {
        return groupMemberDao.searchMembersCount(conditions);
    }

    @Override
    public List<Map<String, Object>> searchMembers(Map<String, Object> conditions, OrderBy orderBy,
                                                   int start, int limit) {

        return groupMemberDao.searchMembers(conditions, orderBy, start, limit);
    }

    @Override
    public Map<String, Object> getMemberByGroupIdAndUserId(Integer groupId, Integer userId) {
        return groupMemberDao.getMemberByGroupIdAndUserId(groupId, userId);
    }

    @Override
    public void changeGroupBackgroundLogo(Integer id, String filePath, Map<String, Object> options) {
        Map<String, Object> group = getGroup(id);
        Map<String, Object> mediumFileRecord = this.changeLogo(filePath, 1140, 279,
                options, String.valueOf(group.get("backgroundLogo")));

        groupDao.updateGroup(id,
                FastHashMap.build(1).add("backgroundlogo", mediumFileRecord.get("uri")).toMap());
    }

    @Override
    public void changeGroupLogo(Integer id, String filePath, Map<String, Object> options) {
        Map<String, Object> group = getGroup(id);
        Map<String, Object> mediumFileRecord = this.changeLogo(filePath, 120, 120,
                options, String.valueOf(group.get("logo")));

        groupDao.updateGroup(id,
                FastHashMap.build(1).add("logo", mediumFileRecord.get("uri")).toMap());
    }

    @Override
    public Map<String, Map<String, Object>> getGroupsByIds(Set<Object> groupIds) {
        List<Map<String, Object>> groups = groupDao.getGroupsByIds(groupIds);
        return ArrayToolkit.index(groups, "id");
    }

    @Override
    public void updateGroup(Integer id, Map<String, Object> fields) {
        if (EasyStringUtil.isNotBlank(fields.get("about"))) {
            fields.put("about", EasyStringUtil.purifyHtml(fields.get("about")));
        }
        groupDao.updateGroup(id, fields);
    }

    private Map<String, Object> changeLogo(String filePath, int newWidth, int newHeight,
                                           Map<String, Object> options, String logoUrl){

        AppPathInfo pathInfo = new AppPathInfo(filePath);
        String cropImageFilePath = pathInfo.getDirname() + "/" + pathInfo.getFilename() + "_crop." + pathInfo.getExtension();
        int x = (int)ValueParser.parseFloat(options.get("x"));
        int y = (int)ValueParser.parseFloat(options.get("y"));
        int width = (int)ValueParser.parseFloat(options.get("width"));
        int height = (int)ValueParser.parseFloat(options.get("height"));
        ImageUtil.cropPartImage(filePath, cropImageFilePath, pathInfo.getExtension(), x, y, width, height);

        String mediumFilePath = pathInfo.getDirname() + "/" + pathInfo.getFilename() + "_medium." + pathInfo.getExtension();
        try {
            ImageUtil.resizeImage(cropImageFilePath, mediumFilePath, pathInfo.getExtension(), newWidth, 0.9f);
        } catch (Exception e) {
            throw new RuntimeGoingException("Resize group logo image error: " + e.getMessage());
        }

        return fileService.uploadFile("user", new File(mediumFilePath));
    }

}
